package cn.iocoder.yudao.module.iot.gateway.protocol.custom.xiaoan.tcp.router.handler;

import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.gateway.protocol.custom.xiaoan.tcp.router.handler.message.ResponseHandler;
import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.manager.IotTcpConnectionManager;
import cn.iocoder.yudao.module.iot.gateway.protocol.tcp.router.handler.BaseProtocolHandler;
import cn.iocoder.yudao.module.iot.gateway.service.device.message.IotDeviceMessageService;
import io.vertx.core.net.NetSocket;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;

@Slf4j
@Component
public class XiaoAnBusinessProtocolHandler extends BaseProtocolHandler {
    @Resource
    private IotDeviceMessageService deviceMessageService;
    @Resource
    private IotTcpConnectionManager connectionManager;
    // 注入所有消息处理器
    @Resource
    private List<ResponseHandler> messageHandlers;

    @Override
    public void handle(String clientId, IotDeviceMessage message, String codecType, NetSocket socket, String serviceId) {
        handleBusinessRequest(clientId, message, codecType, socket, serviceId);
    }

    @Override
    public String getHandlerType() {
        return super.getHandlerType();
    }

    @Override
    public String getProtocolType() {
        return "xiaoan";
    }

    /**
     * 处理业务请求
     *
     * @param clientId  客户端 ID
     * @param message   消息信息
     * @param codecType 消息编解码类型
     * @param socket    网络连接
     */
    private void handleBusinessRequest(String clientId, IotDeviceMessage message, String codecType, NetSocket socket, String serverId) {
        try {
            // 1. 检查认证状态
            if (connectionManager.isNotAuthenticated(socket)) {
                log.warn("[handleBusinessRequest][设备未认证，客户端 ID: {}]", clientId);
                // 如果设备没有登录，其他数据包一概丢弃。
                return;
            }

            // 2.1 根据 method 查找对应响应的处理器
            String method = message.getMethod();
            ResponseHandler handler = findHandler(method);

            // 2.3 上行消息响应,没有找到对应的handler,则无响应
            if (handler != null) {
                handler.handle(socket, message, codecType, clientId, serverId);
            }

            // 3. 获取认证信息并处理业务消息
            IotTcpConnectionManager.ConnectionInfo connectionInfo = connectionManager.getConnectionInfo(socket);

            // 4. 发送消息到消息总线
            deviceMessageService.sendDeviceMessage(message, connectionInfo.getProductKey(),
                    connectionInfo.getDeviceName(), serverId);
            log.info("[handleBusinessRequest][发送消息到消息总线，客户端 ID: {}，消息: {}",
                    clientId, message.toString());
        } catch (Exception e) {
            log.error("[handleBusinessRequest][业务请求处理异常，客户端 ID: {}]", clientId, e);
        }
    }

    /**
     * 查找支持指定方法的消息处理器
     */
    private ResponseHandler findHandler(String method) {
        for (ResponseHandler handler : messageHandlers) {
            if (handler.supports(method)) {
                return handler;
            }
        }
        return null;
    }

}
